package org.lemon.transport.http.controller;

import org.lemon.transport.http.service.DeviceTransportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.http.HttpServletRequest;

@RestController
public class DeviceTransportController {

    @Autowired
    private DeviceTransportService deviceTransportService;

    /**
     * 获取设备属性值
     * 响应示例:
     * {
     * "stringKey":"value1",
     * "booleanKey\":true,
     * "doubleKey\":42.0,
     * "longKey\":73,
     * "jsonKey": {
     * "someNumber": 42,
     * "someArray": [1,2,3],
     * "someNestedObject": {"key": "key_value"}
     * }
     * }
     *
     * @param deviceToken
     * @param clientKeys
     * @param sharedKeys
     * @return
     */
    @RequestMapping(value = "/api/v1/{deviceToken}/attributes", method = RequestMethod.GET, produces = "application/json")
    public DeferredResult<ResponseEntity<String>> getDeviceAttributes(
            @PathVariable("deviceToken") String deviceToken,
            @RequestParam(value = "clientKeys", required = false, defaultValue = "") String clientKeys,
            @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys) {

        return deviceTransportService.getDeviceAttributes(deviceToken, clientKeys, sharedKeys);
    }

    /**
     * 提交设备属性值
     * 请求示例:
     * {
     * "stringKey":"value1",
     * "booleanKey\":true,
     * "doubleKey\":42.0,
     * "longKey\":73,
     * "jsonKey": {
     * "someNumber": 42,
     * "someArray": [1,2,3],
     * "someNestedObject": {"key": "key_value"}
     * }
     * }
     *
     * @param deviceToken
     * @param json
     * @return
     */
    @RequestMapping(value = "/api/v1/{deviceToken}/attributes", method = RequestMethod.POST)
    public DeferredResult<ResponseEntity<Void>> postDeviceAttributes(
            @PathVariable("deviceToken") String deviceToken,
            @RequestBody String json) {

        return deviceTransportService.postDeviceAttributes(deviceToken, json);
    }

    /**
     * 提交设备遥测数据, 保存在时序数据库中
     * 请求示例:
     * Single JSON object
     * {"ts":1634712287000,"values":{"temperature":26, "humidity":87}}
     * JSON array
     * [
     * {"ts":1634712287000,"values":{"temperature":26, "humidity":87}},
     * {"ts":1634712588000,"values":{"temperature":25, "humidity":88}}
     * ]
     *
     * @param deviceToken
     * @param json
     * @param request
     * @return
     */
    @RequestMapping(value = "/api/v1/{deviceToken}/telemetry", method = RequestMethod.POST)
    public DeferredResult<ResponseEntity<Void>> postTelemetry(
            @PathVariable("deviceToken") String deviceToken,
            @RequestBody String json, HttpServletRequest request) {

        return deviceTransportService.postTelemetry(deviceToken, json, request);
    }

    /**
     * 保存用户认领设备所需的信息。请参阅相应的“声称设备”平台文档中有关声称的更多信息
     * \n 请求示例: "{"secretKey":"value", "durationMs":60000}"
     *
     * @param deviceToken
     * @param json
     * @return
     */
    @RequestMapping(value = "/api/v1/{deviceToken}/claim", method = RequestMethod.POST)
    public DeferredResult<ResponseEntity<Void>> claimDevice(
            @PathVariable("deviceToken") String deviceToken,
            @RequestBody(required = false) String json) {

        return deviceTransportService.claimDevice(deviceToken, json);
    }

    /**
     * 交换设备凭证
     * 请求示例:
     * {
     * "deviceName": "NEW_DEVICE_NAME",
     * "provisionDeviceKey": "u7piawkboq8v32dmcmpp",
     * "provisionDeviceSecret": "jpmwdn8ptlswmf4m29bw"
     * }
     * 响应示例:
     * {
     * "credentialsType":"ACCESS_TOKEN",
     * "credentialsValue":"DEVICE_ACCESS_TOKEN",
     * "status":"SUCCESS"
     * }
     *
     * @param json
     * @return
     */
    @RequestMapping(value = "/api/v1/provision", method = RequestMethod.POST)
    public DeferredResult<ResponseEntity<String>> provisionDevice(@RequestBody String json) {

        return deviceTransportService.provisionDevice(json);
    }
}
